package cn.chendd.example.jpa.nativequery;

import cn.chendd.example.jpa.nativequery.annotions.Query;
import cn.chendd.example.jpa.nativequery.enums.ResultSetType;

import javax.persistence.EntityManager;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.MissingResourceException;

/**
 * @author chendd
 * @date 2020/5/6
 */
public class SQLQueryHanlder implements InvocationHandler {

    private EntityManager entityManager;

    public SQLQueryHanlder(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Query query = method.getAnnotation(Query.class);
        if(query == null) {
            throw new MissingResourceException("This method is missing an annotation declaration", getClass().getName() , method.getName());
        }
        ResultSetType resultSetType = query.resultSet().resultSetType();
        Object result = this.getEntityManagerAndQuery(query , resultSetType.getClassName() , method , args);
        return result;
    }

    private Object getEntityManagerAndQuery(Query query, Class<? extends SQLQuery> classHandler , Method method, Object[] args) {
        SQLQuery sqlQuery = null;
        try {
            sqlQuery = classHandler.newInstance();
            sqlQuery.setEntityManager(this.entityManager);
            sqlQuery.setQuery(query);
            sqlQuery.setMethod(method);
        } catch (InstantiationException | IllegalAccessException e) {
            throw new UnsupportedOperationException(e);
        }
        return sqlQuery.doExecute(args);
    }

}
